﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DAL.Helpers;
using Model.Entities;
using Model.RepositoryInterfaces;
using Model.ViewModels;
using NHibernate;

namespace DAL.Repositories
{
    public class ApartmentRepository:IApartmentRepository
    {
        #region Implementation of IApartmentRepository

        public void Create(Apartment apartment)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    try
                    {
                        session.Save(apartment);
                        transaction.Commit();
                    }
                    catch (ADOException exception)
                    {
                        throw new Exception(exception.Message);
                    }
                }
            }
        }

        public Apartment Read(int apartmentId)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var apartment = session.Get<Apartment>(apartmentId);
                return apartment;
            }
        }

        public ApartmentDetailsVm ReadDetails(int apartmentId)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var apartment = session.Get<Apartment>(apartmentId);

                if (apartment != null)
                {
                    var detailsViewModel = new ApartmentDetailsVm()
                    {
                        Id = apartment.Id,
                        Code = apartment.Code,
                        Building = apartment.Building,
                        State = EnumHelper.GetEnumName(typeof(ApartmentState), apartment.State),
                        Floor = EnumHelper.GetEnumName(typeof(Floor), apartment.Floor),
                        RoomsNumber = EnumHelper.GetEnumName(typeof(NumOfRooms), apartment.NumOfRooms),
                        Facade = EnumHelper.GetEnumName(typeof(ApartmentFacade), apartment.Facade),
                        Price = Math.Round(apartment.Price, 2),
                        Area = apartment.Area,
                        HasTwoFloors = apartment.HasTwoFloors
                    };

                    return detailsViewModel;
                }
                else
                {
                    return new ApartmentDetailsVm();
                }
            }
        }

        public IList<ApartmentListAdminVm> ReadAll()
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var query = session.CreateQuery("from Apartment");
                var list = query.List<Apartment>();

                return list.Select(apartment => new ApartmentListAdminVm()
                {
                    Id = apartment.Id, 
                    Code = apartment.Code, 
                    Building = apartment.Building, 
                    State = EnumHelper.GetEnumName(typeof (ApartmentState), apartment.State), 
                    Floor = EnumHelper.GetEnumName(typeof (Floor), apartment.Floor), 
                    NumOfRooms = EnumHelper.GetEnumName(typeof (NumOfRooms), apartment.NumOfRooms), 
                    Facade = EnumHelper.GetEnumName(typeof (ApartmentFacade), apartment.Facade), 
                    Model = apartment.Model, 
                    Price = apartment.Price, 
                    Area = apartment.Area,
                    HasTwoFloors = apartment.HasTwoFloors
                }).ToList();
            }
        }

        public IList<ApartmentsGraphicsVm> ReadGraphics()
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var query = session.CreateQuery("from Apartment");
                var list = query.List<Apartment>();

                return list.Select(apartment => new ApartmentsGraphicsVm()
                {
                    Id = apartment.Id,
                    Code = apartment.Code,
                    Layout = "www.ban-centar.hr/Content/Images/Layout/" + apartment.Code + ".png",
                    LayoutThumb = "www.ban-centar.hr/Content/Images/Layout/Thumb/" + apartment.Code + ".png",
                    TopView = "www.ban-centar.hr/Content/Images/TopView/" + apartment.Code + ".png",
                    TopViewThumb = "www.ban-centar.hr/Content/Images/TopView/Thumb/" + apartment.Code + ".png",
                    Table = "www.ban-centar.hr/Content/Images/Table/" + apartment.Code + ".png"
                }).ToList();
            }
        }

        public IList<ApartmentListAdminVm> ReadByCode(string code)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var query = session.CreateQuery("from Apartment where Code = :code").SetParameter("code", code);
                var list = query.List<Apartment>();

                return list.Select(apartment => new ApartmentListAdminVm()
                {
                    Id = apartment.Id, 
                    Code = apartment.Code, 
                    Building = apartment.Building, 
                    State = EnumHelper.GetEnumName(typeof (ApartmentState), apartment.State), 
                    Floor = EnumHelper.GetEnumName(typeof (Floor), apartment.Floor), 
                    NumOfRooms = EnumHelper.GetEnumName(typeof (NumOfRooms), apartment.NumOfRooms), 
                    Facade = EnumHelper.GetEnumName(typeof (ApartmentFacade), apartment.Facade), 
                    Model = apartment.Model, 
                    Price = apartment.Price, 
                    Area = apartment.Area
                 }).ToList();
            }
        }

        public IList<ApartmentListAdminVm> ReadByModel(string model)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var query = session.CreateQuery("from Apartment where Model = :model").SetParameter("model", model);
                var list = query.List<Apartment>();

                return list.Select(apartment => new ApartmentListAdminVm()
                {
                    Id = apartment.Id, 
                    Code = apartment.Code, 
                    Building = apartment.Building, 
                    State = EnumHelper.GetEnumName(typeof (ApartmentState), apartment.State), 
                    Floor = EnumHelper.GetEnumName(typeof (Floor), apartment.Floor), 
                    NumOfRooms = EnumHelper.GetEnumName(typeof (NumOfRooms), apartment.NumOfRooms), 
                    Facade = EnumHelper.GetEnumName(typeof (ApartmentFacade), apartment.Facade), 
                    Model = apartment.Model, 
                    Price = apartment.Price,
                    Area = apartment.Area
                }).ToList();
            }
        }

        public void Update(Apartment apartment)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    try
                    {
                        session.Update(apartment);

                        var updatedApartment = session.Get<Apartment>(apartment.Id);
                        updatedApartment.IndexTable.Code = apartment.Code;
                        updatedApartment.IndexTable.Floor = EnumHelper.GetEnumName(typeof(Floor), apartment.Floor);
                        updatedApartment.IndexTable.NumOfRooms = EnumHelper.GetEnumName(typeof(NumOfRooms), apartment.NumOfRooms);
                        updatedApartment.IndexTable.Facade = EnumHelper.GetEnumName(typeof(ApartmentFacade), apartment.Facade);

                        session.Update(updatedApartment);

                        transaction.Commit();
                    }
                    catch (ADOException exception)
                    {
                        throw new Exception(exception.Message);
                    }
                }
            }
        }

        public void Delete(int apartmentId)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    try
                    {
                        var apartment = session.Get<Apartment>(apartmentId);
                        session.Delete(apartment);
                        transaction.Commit();
                    }
                    catch (ADOException exception)
                    {
                        throw new Exception(exception.Message);
                    }
                }
            }
        }

        #endregion
    }
}
